﻿using AladdinGameFramework.ObjectPool;
using AladdinGameFramework.Resource;
using System;

namespace AladdinGameFramework.Entity
{
	/// <summary>
	/// 实体管理器接口。
	/// </summary>
	public interface IEntityManager
	{
		/// <summary>
		/// 获取实体数量。
		/// </summary>
		int EntityCount
		{
			get;
		}

		/// <summary>
		/// 获取实体组数量。
		/// </summary>
		int EntityGroupCount
		{
			get;
		}

		/// <summary>
		/// 显示实体成功事件。
		/// </summary>
		event EventHandler<ShowEntitySuccessEventArgs> ShowEntitySuccess;

		/// <summary>
		/// 显示实体失败事件。
		/// </summary>
		event EventHandler<ShowEntityFailureEventArgs> ShowEntityFailure;

		/// <summary>
		/// 显示实体更新事件。
		/// </summary>
		event EventHandler<ShowEntityUpdateEventArgs> ShowEntityUpdate;

		/// <summary>
		/// 显示实体时加载依赖资源事件。
		/// </summary>
		event EventHandler<ShowEntityDependencyAssetEventArgs> ShowEntityDependencyAsset;

		/// <summary>
		/// 隐藏实体完成事件。
		/// </summary>
		event EventHandler<HideEntityCompleteEventArgs> HideEntityComplete;

		/// <summary>
		/// 设置对象池管理器。
		/// </summary>
		/// <param name="objectPoolManager">对象池管理器。</param>
		void SetObjectPoolManager(IObjectPoolManager objectPoolManager);

		/// <summary>
		/// 设置资源管理器。
		/// </summary>
		/// <param name="resourceManager">资源管理器。</param>
		void SetResourceManager(IResourceManager resourceManager);

		/// <summary>
		/// 设置实体辅助器。
		/// </summary>
		/// <param name="entityHelper">实体辅助器。</param>
		void SetEntityHelper(IEntityHelper entityHelper);

		/// <summary>
		/// 是否存在实体组。
		/// </summary>
		/// <param name="entityGroupName">实体组名称。</param>
		/// <returns>是否存在实体组。</returns>
		bool HasEntityGroup(string entityGroupName);

		/// <summary>
		/// 获取实体组。
		/// </summary>
		/// <param name="entityGroupName">实体组名称。</param>
		/// <returns>要获取的实体组。</returns>
		IEntityGroup GetEntityGroup(string entityGroupName);

		/// <summary>
		/// 获取所有实体组。
		/// </summary>
		/// <returns>所有实体组。</returns>
		IEntityGroup[] GetAllEntityGroups();

		/// <summary>
		/// 增加实体组。
		/// </summary>
		/// <param name="entityGroupName">实体组名称。</param>
		/// <param name="instanceAutoReleaseInterval">实体实例对象池自动释放可释放对象的间隔秒数。</param>
		/// <param name="instanceCapacity">实体实例对象池容量。</param>
		/// <param name="instanceExpireTime">实体实例对象池对象过期秒数。</param>
		/// <param name="instancePriority">实体实例对象池的优先级。</param>
		/// <param name="entityGroupHelper">实体组辅助器。</param>
		/// <returns>是否增加实体组成功。</returns>
		bool AddEntityGroup(string entityGroupName, float instanceAutoReleaseInterval, int instanceCapacity, float instanceExpireTime, int instancePriority, IEntityGroupHelper entityGroupHelper);

		/// <summary>
		/// 是否存在实体。
		/// </summary>
		/// <param name="entityId">实体编号。</param>
		/// <returns>是否存在实体。</returns>
		bool HasEntity(int entityId);

		/// <summary>
		/// 是否存在实体。
		/// </summary>
		/// <param name="entityAssetName">实体资源名称。</param>
		/// <returns>是否存在实体。</returns>
		bool HasEntity(string entityAssetName);

		/// <summary>
		/// 获取实体。
		/// </summary>
		/// <param name="entityId">实体编号。</param>
		/// <returns>要获取的实体。</returns>
		IEntity GetEntity(int entityId);

		/// <summary>
		/// 获取实体。
		/// </summary>
		/// <param name="entityAssetName">实体资源名称。</param>
		/// <returns>要获取的实体。</returns>
		IEntity GetEntity(string entityAssetName);

		/// <summary>
		/// 获取实体。
		/// </summary>
		/// <param name="entityAssetName">实体资源名称。</param>
		/// <returns>要获取的实体。</returns>
		IEntity[] GetEntities(string entityAssetName);

		/// <summary>
		/// 获取所有已加载的实体。
		/// </summary>
		/// <returns>所有已加载的实体。</returns>
		IEntity[] GetAllLoadedEntities();

		/// <summary>
		/// 获取所有正在加载实体的编号。
		/// </summary>
		/// <returns>所有正在加载实体的编号。</returns>
		int[] GetAllLoadingEntityIds();

		/// <summary>
		/// 是否正在加载实体。
		/// </summary>
		/// <param name="entityId">实体编号。</param>
		/// <returns>是否正在加载实体。</returns>
		bool IsLoadingEntity(int entityId);

		/// <summary>
		/// 是否是合法的实体。
		/// </summary>
		/// <param name="entity">实体。</param>
		/// <returns>实体是否合法。</returns>
		bool IsValidEntity(IEntity entity);

		/// <summary>
		/// 显示实体。
		/// </summary>
		/// <param name="entityId">实体编号。</param>
		/// <param name="entityAssetName">实体资源名称。</param>
		/// <param name="entityGroupName">实体组名称。</param>
		void ShowEntity(int entityId, string entityAssetName, string entityGroupName);

		/// <summary>
		/// 显示实体。
		/// </summary>
		/// <param name="entityId">实体编号。</param>
		/// <param name="entityAssetName">实体资源名称。</param>
		/// <param name="entityGroupName">实体组名称。</param>
		/// <param name="userData">用户自定义数据。</param>
		void ShowEntity(int entityId, string entityAssetName, string entityGroupName, object userData);

		/// <summary>
		/// 隐藏实体。
		/// </summary>
		/// <param name="entityId">实体编号。</param>
		void HideEntity(int entityId);

		/// <summary>
		/// 隐藏实体。
		/// </summary>
		/// <param name="entityId">实体编号。</param>
		/// <param name="userData">用户自定义数据。</param>
		void HideEntity(int entityId, object userData);

		/// <summary>
		/// 隐藏实体。
		/// </summary>
		/// <param name="entity">实体。</param>
		void HideEntity(IEntity entity);

		/// <summary>
		/// 隐藏实体。
		/// </summary>
		/// <param name="entity">实体。</param>
		/// <param name="userData">用户自定义数据。</param>
		void HideEntity(IEntity entity, object userData);

		/// <summary>
		/// 隐藏所有已加载的实体。
		/// </summary>
		void HideAllLoadedEntities();

		/// <summary>
		/// 隐藏所有已加载的实体。
		/// </summary>
		/// <param name="userData">用户自定义数据。</param>
		void HideAllLoadedEntities(object userData);

		/// <summary>
		/// 隐藏所有正在加载的实体。
		/// </summary>
		void HideAllLoadingEntities();

		/// <summary>
		/// 获取父实体。
		/// </summary>
		/// <param name="childEntityId">要获取父实体的子实体的实体编号。</param>
		/// <returns>子实体的父实体。</returns>
		IEntity GetParentEntity(int childEntityId);

		/// <summary>
		/// 获取父实体。
		/// </summary>
		/// <param name="childEntity">要获取父实体的子实体。</param>
		/// <returns>子实体的父实体。</returns>
		IEntity GetParentEntity(IEntity childEntity);

		/// <summary>
		/// 获取子实体。
		/// </summary>
		/// <param name="parentEntityId">要获取子实体的父实体的实体编号。</param>
		/// <returns>子实体数组。</returns>
		IEntity[] GetChildEntities(int parentEntityId);

		/// <summary>
		/// 获取子实体。
		/// </summary>
		/// <param name="parentEntity">要获取子实体的父实体。</param>
		/// <returns>子实体数组。</returns>
		IEntity[] GetChildEntities(IEntity parentEntity);

		/// <summary>
		/// 附加子实体。
		/// </summary>
		/// <param name="childEntityId">要附加的子实体的实体编号。</param>
		/// <param name="parentEntityId">被附加的父实体的实体编号。</param>
		void AttachEntity(int childEntityId, int parentEntityId);

		/// <summary>
		/// 附加子实体。
		/// </summary>
		/// <param name="childEntityId">要附加的子实体的实体编号。</param>
		/// <param name="parentEntityId">被附加的父实体的实体编号。</param>
		/// <param name="userData">用户自定义数据。</param>
		void AttachEntity(int childEntityId, int parentEntityId, object userData);

		/// <summary>
		/// 附加子实体。
		/// </summary>
		/// <param name="childEntityId">要附加的子实体的实体编号。</param>
		/// <param name="parentEntity">被附加的父实体。</param>
		void AttachEntity(int childEntityId, IEntity parentEntity);

		/// <summary>
		/// 附加子实体。
		/// </summary>
		/// <param name="childEntityId">要附加的子实体的实体编号。</param>
		/// <param name="parentEntity">被附加的父实体。</param>
		/// <param name="userData">用户自定义数据。</param>
		void AttachEntity(int childEntityId, IEntity parentEntity, object userData);

		/// <summary>
		/// 附加子实体。
		/// </summary>
		/// <param name="childEntity">要附加的子实体。</param>
		/// <param name="parentEntityId">被附加的父实体的实体编号。</param>
		void AttachEntity(IEntity childEntity, int parentEntityId);

		/// <summary>
		/// 附加子实体。
		/// </summary>
		/// <param name="childEntity">要附加的子实体。</param>
		/// <param name="parentEntityId">被附加的父实体的实体编号。</param>
		/// <param name="userData">用户自定义数据。</param>
		void AttachEntity(IEntity childEntity, int parentEntityId, object userData);

		/// <summary>
		/// 附加子实体。
		/// </summary>
		/// <param name="childEntity">要附加的子实体。</param>
		/// <param name="parentEntity">被附加的父实体。</param>
		void AttachEntity(IEntity childEntity, IEntity parentEntity);

		/// <summary>
		/// 附加子实体。
		/// </summary>
		/// <param name="childEntity">要附加的子实体。</param>
		/// <param name="parentEntity">被附加的父实体。</param>
		/// <param name="userData">用户自定义数据。</param>
		void AttachEntity(IEntity childEntity, IEntity parentEntity, object userData);

		/// <summary>
		/// 解除子实体。
		/// </summary>
		/// <param name="childEntityId">要解除的子实体的实体编号。</param>
		void DetachEntity(int childEntityId);

		/// <summary>
		/// 解除子实体。
		/// </summary>
		/// <param name="childEntityId">要解除的子实体的实体编号。</param>
		/// <param name="userData">用户自定义数据。</param>
		void DetachEntity(int childEntityId, object userData);

		/// <summary>
		/// 解除子实体。
		/// </summary>
		/// <param name="childEntity">要解除的子实体。</param>
		void DetachEntity(IEntity childEntity);

		/// <summary>
		/// 解除子实体。
		/// </summary>
		/// <param name="childEntity">要解除的子实体。</param>
		/// <param name="userData">用户自定义数据。</param>
		void DetachEntity(IEntity childEntity, object userData);

		/// <summary>
		/// 解除所有子实体。
		/// </summary>
		/// <param name="parentEntityId">被解除的父实体的实体编号。</param>
		void DetachChildEntities(int parentEntityId);

		/// <summary>
		/// 解除所有子实体。
		/// </summary>
		/// <param name="parentEntityId">被解除的父实体的实体编号。</param>
		/// <param name="userData">用户自定义数据。</param>
		void DetachChildEntities(int parentEntityId, object userData);

		/// <summary>
		/// 解除所有子实体。
		/// </summary>
		/// <param name="parentEntity">被解除的父实体。</param>
		void DetachChildEntities(IEntity parentEntity);

		/// <summary>
		/// 解除所有子实体。
		/// </summary>
		/// <param name="parentEntity">被解除的父实体。</param>
		/// <param name="userData">用户自定义数据。</param>
		void DetachChildEntities(IEntity parentEntity, object userData);

		/// <summary>
		/// 设置实体实例是否被加锁。
		/// </summary>
		/// <param name="entity">实体。</param>
		/// <param name="locked">实体实例是否被加锁。</param>
		void SetInstanceLocked(IEntity entity, bool locked);

		/// <summary>
		/// 设置实体实例的优先级。
		/// </summary>
		/// <param name="entity">实体。</param>
		/// <param name="priority">实体实例优先级。</param>
		void SetInstancePriority(IEntity entity, int priority);
	}
}
